﻿namespace NuGetCop.MSBuild.Tasks.Foundation
{
    using System;
    using System.Diagnostics.Contracts;
    using System.Threading;
    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities;

    public abstract class CancelableTask : Task, ICancelableTask, IDisposable
    {
        private readonly CancellationTokenSource cancellationTokenSource;

        protected CancelableTask()
        {
            cancellationTokenSource = new CancellationTokenSource();
        }

        ~CancelableTask()
        {
            Dispose(false);
        }

        protected CancellationToken CancellationToken
        {
            get
            {
                return cancellationTokenSource.Token;
            }
        }

        public void Cancel()
        {
            cancellationTokenSource.Cancel(true);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            cancellationTokenSource.Dispose();
        }

        [ContractInvariantMethod]
        private void ObjectInvariant()
        {
            Contract.Invariant(cancellationTokenSource != null);
        }
    }
}
